var address_location = null;
//var test = 0;

function BuildPoint(x,y){
  return new Microsoft.Maps.Location(x, y);
}

function Service(element){
  this.type = element.getAttribute("type");
  this.name = element.getAttribute("name");
  this.phone= element.getAttribute("phone");
  this.grade = element.getAttribute("grade");
  //this.email= element.getAttribute("email");
  //this.suburb = element.getAttribute("local");
  //this.city = element.getAttribute("city");
  //this.region = element.getAttribute("region");
  //this.privilege= element.getAttribute("privilege");
  //this.activity= element.getAttribute("activity");
  //this.icon= element.getAttribute("icon");
  this.address =  element.getElementsByTagName("address")[0].firstChild.data;
  if (element.getElementsByTagName("description")[0].firstChild != null) {
    this.description = element.getElementsByTagName("description")[0].firstChild.data;
  } else {
    this.description = "";
  }

/*  this.special_description= element.getAttribute("special_description");
  this.special_rate= element.getAttribute("special_rate");
  this.special_start= element.getAttribute("special_start");
  this.special_end= element.getAttribute("special_end");*/

  var loc_string = element.getElementsByTagName("latlong")[0].firstChild.data.split(",",2);
  this.loc = BuildPoint(parseFloat(loc_string[0])/1000000,parseFloat(loc_string[1])/1000000);
  this.days = {}
  this.in_square = false;

/*  var working_days = element.getElementsByTagName("days")[0].firstChild.data.split(',');
  for(var i=0;i<working_days.length;i++){
     this.days[working_days[i]] = true;   
  }*/

  this.active = true;
/*  this.WorkingDaysStr = function(){
    var ret = [];
    var ds = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
    for(var i=0;i<ds.length;i++){
      if(this.days[ds[i]]){
        ret.push(ds[i]);
      }
    }
    return ret.join(','); 
  }*/
}

function AgeFilter(low,high){
    this.low = low;
    this.high = high;
    this.filt = function (service){
      return true;
      if (service.age.high >= this.low && service.age.low <= this.high){
        return true;
      }else{
        return false;
      }
    }
}
function WorkingDayFilter(){
  this.slots = {'Mon':true,'Tue':true,'Wed':true,'Thu':true,'Fri':true,'Sat':true,'Sun':true};
  this.keys = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'];
  this.filt = function (service){
    if(service.type == "Report"){
      return true;
    }else{
      for(var i=0;i<this.keys.length;i++){
        if(this.slots[this.keys[i]] && service.days[this.keys[i]]){
          return true
        }
      }
    }
    return false;
  }
}
function TypeFilter(){
  this.check = {'mixed':true,'Shop':true,'Report':true}
  this.filt = function(service){
    var type = service.type;
    if(type != "Report"){
       type = "Shop"
    }
    if(this.check[type] == true){
      return true;
    }else{
      return false;
    }
  } 
}

function filt(service,filters){
  var filter_idx = 0;
  for(;filter_idx<filters.length;filter_idx++){
    if(! filters[filter_idx].filt(service)){return false}
  }
  return true;
}
function TargetPlaceJSON(result){
  if(result.resourceSets){
    if(result.resourceSets[0].estimatedTotal = 0){
      zoyoe.ALERT('Address Not Found !!');
    }
    else if(result.resourceSets[0].estimatedTotal = 1){
      var resources = result.resourceSets[0].resources;
      if(resources.length == 0){
        BuildErrorMsg('Address Not Found !!');
      }else if(resources.length == 1){
        zoyoe.ALERT(resources[0].address.formattedAddress);
        var c = resources[0].point.coordinates;
        zoyoe.ALERT(c);
        zoyoe.map.map.setView({center:new Microsoft.Maps.Location(c[0],c[1])});
      }else{
        zoyoe.ALERT("Ambiguious Address, Please Make It Clear !!");
      }
    }
    else{
      zoyoe.ALERT('Multi Address Found,Please Make It Clear !!');
    }
  }
}
function ServiceGeoGroup(service){
  var self = this;
  this.loc = service.loc;
  this.type = service.type;
  this.grade = service.grade;
  this.service_list = new Array();
  this.pushpin = new Microsoft.Maps.Pushpin(this.loc,{anchor:{x:15,y:15},height:39,width:39, textOffset:new Microsoft.Maps.Point(0,8)});
  
  this.mouseover = Microsoft.Maps.Events.addHandler(this.pushpin,'click',
    function(e){
      if(zoyoe){
        var gp = zoyoe.map.map.tryLocationToPixel(self.loc,Microsoft.Maps.PixelReference.page);
        zoyoe.ShowShortCut(self.loc,gp,self.service_list,0);
      }
    });

  //Microsoft.Maps.Events.addHandler(zoyoe.map.map, 'click', zoyoe.CloseShortCut); move this line to home.js
      if (service.grade >3) {
         act_pin = "/res/pushpin/heartVIP.gif";
      } else {
         act_pin = "/res/pushpin/heartRed.png";
      }
      this.pushpin.setOptions({icon:act_pin});

  this.Absorb = function(service){
    this.service_list.push(service);
  }
  this.Absorb(service);
}
function Layer(){
  this.geo_service_group = new Array();
  this.layer = null;
  this.status = "not_ready";
  this.BuildIcons = function(){
    for(var i=0;i<this.geo_service_group.length;i++){
      this.geo_service_group[i].BuildIcon(true);
    }
  }
  this.Show = function(){
    this.layer.setOptions({visible:true});
  }
  this.Hide = function(){
    this.layer.setOptions({visible:false});
  }
  this.Reset = function(){
    for(var i=0;i<this.geo_service_group.length;i++){
      g = this.geo_service_group[i];
      this.layer.remove(g.pushpin);
    }
    this.geo_service_group = new Array();
    this.status = "not_ready";
  }
}

Microsoft.Maps.loadModule('Microsoft.Maps.Themes.BingTheme', { callback: MapInfoCore });

function MapInfoCore(callback,address,container_id,zoom,disable_handler){
/* Safe self reference */
  var self = this;
  var age_filter_idx = 0;
  var workingday_filter_idx = 1;
  var type_filter_idx = 2;

  this.container_id = container_id;
  this.insertedChild = null;
  this.current_zoom = null;
  this.push_pin_id = 0;
  this.general_map_zoom = 16;
  this.pushpin_layers = new Array();
  this.disable_handler = disable_handler;
  this.refresh_time = 0;

  for(var i=0;i<20;i++){
    this.pushpin_layers[i] = new Layer();
  }
  this.services_cache = new Array();

  this.ResetServiceCache = function(){
    this.services_cache = [];
  }

/* function BrotherFilter(borther){
  this.filt = function(service){
    if service.name == brother then return true else return false;
  }
}

/* All Filter Reset functions*/
  //this.filterlist = new Array(new AgeFilter(16,45),new WorkingDayFilter(),new TypeFilter());

/* Append your Filters here */
  /* this.filterlist.append(new BrotherFilter()) */
  /* onclick = map_core.ResetAAAFilter() */
  /* this.ResetAAAFilter = function(brother){
       this.filterlist[brother_filter_idx].name = brother;
     }|
  */                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
  this.ResetAgeFilter = function (low,high){
    if(high<low){high = low;alert('error');}
    this.filterlist[age_filter_idx].low = low;
    this.filterlist[age_filter_idx].high = high;
    this.Refilt();
  }
  this.ToggleWorkingDayFilter = function(dstr){
    var c = this.filterlist[workingday_filter_idx].slots[dstr]; 
    this.filterlist[workingday_filter_idx].slots[dstr] = (c == true) ? false:true;
    this.Refilt();
  }
  this.ToggleTypeFilter = function(dstr){
    var c = this.filterlist[type_filter_idx];
    if(c.check[dstr] != undefined){
      if(c.check[dstr]){
        c.check[dstr] = false;
      }else{
        c.check[dstr] = true;
      }
    }
    this.Refilt();
  }
  
  if(address){
    this.default_address_point = new Microsoft.Maps.Location(-33.849258422, 151.029342651);
  }else{
    //this.default_address_point = new Microsoft.Maps.Location(-33.889221191, 151.125427246);//Ashfield
    //this.default_address_point = new Microsoft.Maps.Location(-33.869628906, 151.206954956);//Sydney
    //this.default_address_point = new Microsoft.Maps.Location(-33.849258422, 151.029342651);//Auburn
    if(document.getElementById('iphone-warpper'))
      this.default_address_point = new Microsoft.Maps.Location(-33.959628906, 151.318000000);//Sydney
    else
      this.default_address_point = new Microsoft.Maps.Location(-33.85551071166992, 151.208251953125);//Dawes Point
  }

  if(zoom){
    this.default_zoom = zoom;
  }else{
    if(document.getElementById('iphone-warpper'))
      this.default_zoom = 10;
    else
      this.default_zoom = 10;
  }
  this.GetZoom = function(){
    return this.current_zoom;
  }
  this.AddService = function(service){
    this.services_cache.push(service);
  }
/* Check whether a service is near a group or not */
  this.NeighbourAtCurrentZoom = function(group,service){
    var gp = this.map.tryLocationToPixel(group.loc,Microsoft.Maps.PixelReference.page);
    var sp = this.map.tryLocationToPixel(service.loc,Microsoft.Maps.PixelReference.page);
    return (Math.abs(gp.x-sp.x)<=39&&Math.abs(gp.y-sp.y)<=39);
  }
  this.TargetPlace = function(where,cbname){
    var script = document.createElement("script");
    script.setAttribute("type","text/javascript"); 
    script.setAttribute("src",this.SearchUri(where +' ,Australia')+"&jsonp="+cbname);//remove: +' ,Australia'
    if(this.insertedChild != null) {
      document.body.removeChild(this.insertedChild);
    }
    this.insertedChild = document.body.appendChild(script);
  }
  /* Always use the current function to get the current layer */
  this.GetCurrentLayer = function(){
  var layer_id = Math.round(this.map.getZoom());
  if(layer_id >= 20 || ! is_int(layer_id)){
    return null;// Should never go here;
    }else if(this.pushpin_layers[layer_id].filled == true){
      return this.pushpin_layers[layer_id];
    }else{
      return null;// Should never go here;
    }
  }
  this.GetServicesInSquare = function(left,top,width,height){
    for(idx = 0;idx < self.services_cache.length;idx++){
      var service = self.services_cache[idx];
      service.in_square = false;
    }
    var pdx = 0;
    var groups= new Array();
    var layer = this.GetCurrentLayer();
    if (layer == null){
      return groups; /*Should never go here */
    }
    for(pdx = 0;pdx <layer.geo_service_group.length;pdx++){
      var service_group = layer.geo_service_group[pdx];
      var gp = this.map.tryLocationToPixel(service_group.loc,Microsoft.Maps.PixelReference.page);
      if(gp.x>=left&&gp.x<=left+width&&gp.y>=top&&gp.y<=top+height){
        groups.push(service_group);
      }
    }
    return groups;
  }
  this.AbsorbService = function(service){
    var layer_id = Math.round(this.map.getZoom());
/*    if(layer_id >= 20){
      return false;
    }else if(this.pushpin_layers[layer_id].filled == true){
      return false;
    }else{*/
      var layer = this.pushpin_layers[layer_id];
      if(layer.layer == null){
        layer.layer = new VEShapeLayer();
      }
      var pdx = 0;
      for(pdx = 0;pdx <layer.geo_service_group.length;pdx++){
        var service_group = layer.geo_service_group[pdx]
        if(this.NeighbourAtCurrentZoom(service_group,service)){
          service_group.Absorb(service);
          break;
        }
      }
      if(pdx == layer.geo_service_group.length){
        var group = new ServiceGeoGroup(service);
        layer.geo_service_group.push(group);
        layer.layer.push(group.pushpin);
      }
    //}
  }
  this.InitServices = function(){
    var layer_id = Math.round(this.map.getZoom());
    var layer = this.pushpin_layers[layer_id];

    if(layer_id >= 20){
      return false;
    }else if(layer.filled == true){
      return false;
    }else{
      var idx = 0;
      for(idx = 0;idx < self.services_cache.length;idx++){
        self.AbsorbService(self.services_cache[idx]);
      }

      //at this point, all groups are created
      var pdx = 0;
      //alert(layer.geo_service_group.length);
      for(pdx = 0;pdx <layer.geo_service_group.length;pdx++){
        //var group = layer.geo_service_group[pdx];
        var length = layer.geo_service_group[pdx].service_list.length;
        if(length!=1){
          layer.geo_service_group[pdx].pushpin.setOptions({text:length.toString()});
        }
      }

      layer.filled = true;
      this.Refilt();
    }
  }
  this.PreviewService = function(service){
  }
  this.ResetData = function(service_list){
    if(!service_list){
      service_list = [];
    }
    for(var i=0;i<this.pushpin_layers.length;i++){
      layer = this.pushpin_layers[i];
      layer.Reset();
    }
    this.ResetServiceCache();
    var self = this;
    foreach(service_list,function(service){
      self.AddService(service);
    });
    this.ShiftZoom(true)
  }
  this.ShiftZoom = function(force){
    var zoom = Math.round(this.map.getZoom());
    if ((zoom != self.current_zoom || force) && is_int(zoom)){
      if (self.current_zoom !=null){
        if (self.pushpin_layers[self.current_zoom] !=null){
          var layer = self.pushpin_layers[self.current_zoom];
          if(layer.status == 'ready'){
            layer.Hide();
          }
        }
      }
      if(this.pushpin_layers[zoom] !=null){
        var layer = this.pushpin_layers[zoom];
        //layer.BuildIcons();

        if(layer.status == 'ready'){
          layer.Show();
        }else{
          this.InitServices();
          layer.status = 'ready';
          layer.Show();
        }
      }else{
        alert("not_supported:"+zoom);
      }
      self.current_zoom = zoom;
    }else{
    }
  }
  this.key = "Av6myMPPl0Aix9wsk-YXGQ23bvY1A3I2dmHJ44GAVYwlF_70J4OJdmv_SqM1rFJd";
  this.map_options = {credentials:this.key,showDashboard:true,showBreadcrumb:true,showMapTypeSelector:false
  ,mapTypeId:Microsoft.Maps.MapTypeId.road
  ,disableUserInput:false,showCopyright:false,showScalebar:false
  ,enableSearchLogo:false
  ,theme: new Microsoft.Maps.Themes.BingTheme() 
  ,zoom:this.default_zoom,center:this.default_address_point}
  if(disable_handler){
    this.map_options.disableUserInput = false;
  }
  this.current_zoom = this.default_zoom;
  var search_prefix = "http://ecn.dev.virtualearth.net/REST/v1/Locations?key="
                      + this.key + "&query="
  this.SearchUri = function(address){
    //alert(search_prefix + address);
    return search_prefix + address + "&maxResults=1";
  }
  function RearrangeEvents(map_core){
    var this_map=map_core.map;
    var core = map_core;
    Microsoft.Maps.Events.addHandler(this_map,'viewchangeend',
      function(event){
          core.ShiftZoom();
          //var fa = GetMapArea();
          //var groups = core.GetServicesInSquare(fa.left,fa.top,fa.width,fa.height);
          if(map_core.disable_handler != true){
            RefreshServicesInRightDock();
          }
      });
    Microsoft.Maps.Events.addHandler(this_map,'viewchangestart',
      function(event){
        var zoom = core.map.getTargetZoom();
        if (zoom > 16){
          core.map.setView({'zoom':16,'animate':false})
        }
        return true;
      });
  }
  function init_layers(){
    var the_map = self.map;
    RearrangeEvents(self);

    for(var i=0;i<20;i++){
        self.pushpin_layers[i].layer = new Microsoft.Maps.EntityCollection({visible:true});
        self.map.entities.push(self.pushpin_layers[i].layer);
    }
    callback(self);
  }
  this.Refilt = function(){
/*    for(idx = 0;idx < self.services_cache.length;idx++){
      var service = self.services_cache[idx];
      if(filt(service,self.filterlist)){
        service.active = true;
      }else{
        service.active = false;
      }
    }*/
    var zoom = Math.round(this.map.getZoom());
    if(this.pushpin_layers[zoom]){
      //this.pushpin_layers[zoom].BuildIcons();
      goto(); //this goto() enable the map type search to remember user address input
    }
  }
  this.AddFocusService = function(service){
    var services = this.services_cache;
    services.push(service);
    this.ResetData(services);
  }
  if(container_id){
    this.map = new Microsoft.Maps.Map(document.getElementById(container_id),this.map_options);
    init_layers();
  }
}

function GetMapArea(){
  var ele = document.getElementById('map-info');
  return {left:ele.offsetLeft,top:ele.offsetTop
  ,width:ele.offsetWidth
  ,height:ele.offsetHeight};
}



/*
 * Component
 */


function SwitchPlaceJSON(result){
  if(result.resourceSets){
    if(result.resourceSets[0].estimatedTotal = 0){
      zoyoe.ALERT('Address Not Found !!');
    }
    else if(result.resourceSets[0].estimatedTotal = 1){
      var resources = result.resourceSets[0].resources;
      if(resources.length == 0){
        BuildErrorMsg('Address Not Found !!');
      }else if(resources.length == 1){
        var c = resources[0].point.coordinates;
        zoyoe.map.map.setView({center:new Microsoft.Maps.Location(c[0],c[1])});
      }else{
        var select = "<form name='switch-place'><select name='sel'>";
        for(var i = 0; i < resources.length; i++){
          var option_val = resources[i].point.coordinates.join(",");
          select += "<option value='" + option_val + "'>"
            +resources[i].address.formattedAddress+"</option>";
        }
        select += "</select></form>";
        zoyoe.ui.GeneralAlert(select,"Ambiguious Address, Please Make It Clear"
          ,function(){
          var select = document.forms['switch-place'].sel.value;
          var c = select.split(",");
          zoyoe.map.map.setView({center:new Microsoft.Maps.Location(c[0],c[1])});
        },false);
        zoyoe.ALERT("Ambiguious Address, Please Make It Clear !!");
      }
    }
    else{
      zoyoe.ALERT('Multi Address Found,Please Make It Clear !!');
    }
  }
}

